package com.etlmaster.rowprocessor.transformer;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.etlmaster.executor.utils.JsonHelper;


/**
 * Created by wugf on 2016/12/12. 实时处理的流对象
 */
public class Line {

	private FieldEntry[] fieldList;
	private int length;
	private int fieldNum;
	public static final int LINE_MAX_FIELD = 1024;

	private Map<String,Object> extra;
	private Map<String,Integer> colIndex=new HashMap<String,Integer>();
	private boolean skip = false;
	
	private List<Map<String,Object>> targetRowData = new ArrayList<Map<String,Object>>();

	public Line() {
		this.fieldList = new FieldEntry[LINE_MAX_FIELD];
	}

	public void clear() {
		length = 0;
		fieldNum = 0;
	}

	public int length() {
		return length;
	}

	private void updateIndex(){
		getColIndex().clear();
		for(int i=0;i<fieldNum;i++){
			getColIndex().put(fieldList[i].getFieldTable()+"_"+fieldList[i].getFieldName(), i);
		}
	}
	public boolean addField(String field) {
		fieldList[fieldNum] = new FieldEntry(fieldNum+"",fieldNum + "", field);
		fieldNum++;
		if (field != null) {
			length += field.length();
		}
		updateIndex();
		return true;
	}

	public boolean addField(String tableName,String fieldName, String field) {
		fieldList[fieldNum] = new FieldEntry(tableName,fieldName + "", field);
		fieldNum++;
		if (field != null) {
			length += field.length();
		}
		updateIndex();
		return true;
	}

	public boolean addField(String field, int index) {
		if (index < fieldNum) {
			for (int i = fieldNum; i > index; i--) {
				fieldList[i] = fieldList[i - 1];
			}
			fieldNum++;
			fieldList[index] = new FieldEntry(index+"",index + "", field);
			if (field != null) {
				length += field.length();
			}
		}
		if (fieldNum <= index) {
			addField(field);
		}
		updateIndex();
		return true;
	}

	public int getFieldNum() {
		return fieldNum;
	}

	public String getField(int idx) {
		return fieldList[idx].getFieldValue();
	}

	public FieldEntry getEntry(int idx){
		return fieldList[idx];
	}
	public String checkAndGetField(int idx) {
		if (idx < 0 || idx >= fieldNum) {
			return null;
		}
		return fieldList[idx].getFieldValue();
	}

	public StringBuffer toStringBuffer(String separator) {
		StringBuffer tmp = new StringBuffer();
		for (int i = 0; i < fieldNum; i++) {
			tmp.append(fieldList[i].getFieldValue());
			if (i < fieldNum - 1) {
				tmp.append(separator);
			}
		}
		return tmp;
	}

	public String toString(String separator) {
		return this.toStringBuffer(separator).toString();
	}

	public static Line fromJson(String tableName,String lineJson) {
		
		Map<String, String> map = (Map<String, String>) JsonHelper
				.getInstance().read(lineJson);
		
		return fromMap(tableName,map);
	}
	public static Line fromMap(String tableName,Map map){
		Line line = new Line();
		Iterator iter = map.entrySet().iterator();
		while (iter.hasNext()) {
			Map.Entry entry = (Map.Entry) iter.next();
			line.addField(tableName,(String) entry.getKey(), (String) entry.getValue());
		}
		return line;
	}

	public static Line fromString(String tableName,String lineStr, String separator,
			String[] cols) throws Exception {
		String strs[] = lineStr.split(separator);
		Line line = new Line();

		if (cols != null) {
			for (int i = 0; i < strs.length; i++) {
				line.addField(tableName,cols[i], strs[i]);
			}
		}else{
			for (int i = 0; i < strs.length; i++) {
				line.addField(cols[i]);
			}
		}
		return line;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + Arrays.hashCode(fieldList);
		result = prime * result + fieldNum;
		result = prime * result + length;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Line other = (Line) obj;
		if (!Arrays.equals(fieldList, other.fieldList))
			return false;
		if (fieldNum != other.fieldNum)
			return false;
		if (length != other.length)
			return false;
		return true;
	}

	public boolean replaceField(String field, int index) {
		if (index > fieldList.length || index < 0) {
			return false;
		}
		length = length - fieldList[index].getFieldValue().length()
				+ field.length();
		fieldList[index].setFieldValue(field);
		return true;
	}
	
	public boolean replaceFieldName(String sourceTab,String sourceName,String targetName){
		
		Integer sourceIndex = this.getColIndex().get(sourceTab+"_"+sourceName);
		if(sourceIndex==null){
			return false;
		}
		fieldList[sourceIndex].setFieldName(targetName);
		this.getColIndex().remove(sourceTab+"_"+sourceName);
		this.getColIndex().put(sourceTab+"_"+targetName, sourceIndex);
		return true;
	}
	public boolean replaceFieldName(String sourceTab,String sourceName,String targetTable,String targetName){
		
		Integer sourceIndex = this.getColIndex().get(sourceTab+"_"+sourceName);
		if(sourceIndex==null){
			return false;
		}
		fieldList[sourceIndex].setFieldName(targetName);
		fieldList[sourceIndex].setFieldTable(targetTable);
		this.getColIndex().remove(sourceTab+"_"+sourceName);
		this.getColIndex().put(targetTable+"_"+targetName, sourceIndex);
		return true;
	}
	
	public boolean replaceTabName(String targetTab){
		
		for (int i = 0; i < fieldNum; i++) {
			fieldList[i].setFieldTable(targetTab);
		}
		updateIndex();
		return true;
	}

	public boolean isSkip() {
		return skip;
	}

	public void setSkip(boolean skip) {
		this.skip = skip;
	}

	public void deleteField(int index) {
		if (index < fieldNum) {
			length = length - fieldList[index].getFieldValue().length();
			for (int i = index; i < fieldNum; i++) {
				fieldList[i] = fieldList[i + 1];
			}
			fieldNum--;
		}
		updateIndex();
	}

	public Map toMap(){
		Map<String,String> map=new HashMap<String,String>();
		for(int i=0;i<fieldNum;i++){
			FieldEntry entry=this.fieldList[i];
			map.put(entry.getFieldName(), entry.getFieldValue());
		}
		return map;
	}
	public String toJson(){
		
		StringBuffer sb=new StringBuffer();
		sb.append("{");
		for(int i=0;i<fieldNum;i++){
			FieldEntry entry=this.fieldList[i];
			sb.append("\""+entry.getFieldName()+"\":\""+entry.getFieldValue()+"\",");

		}
		sb.deleteCharAt(sb.length()-1);
		sb.append("}");
		
		return sb.toString();
		
	}

	public String toJsons(){
		Map<String,StringBuffer> map=new HashMap<String,StringBuffer>();
		
		for(int i=0;i<fieldNum;i++){
			FieldEntry entry=this.fieldList[i];
			StringBuffer sb=map.get(entry.getFieldTable());
			if(sb==null){
				sb=new StringBuffer();
				sb.append("{");
				map.put(entry.getFieldTable(), sb);
			}
			sb.append("\""+entry.getFieldName()+"\":\""+entry.getFieldValue()+"\",");

		}
		StringBuffer sb=new StringBuffer();
		sb.append("[");
		Iterator it=map.entrySet().iterator();
		while(it.hasNext()){
			Map.Entry<String,StringBuffer> entry=(Entry<String,StringBuffer>) it.next();
			sb.append(JsonHelper.getInstance().write(extra));
			sb.deleteCharAt(sb.length()-1);
			sb.append(",\"tableName\":\""+entry.getKey()+"\",\"data\":{")
			.append(entry.getValue().deleteCharAt(0).deleteCharAt(entry.getValue().length()-1)+"}},");
			
		}
		sb.deleteCharAt(sb.length()-1);
		sb.append("]");

		return sb.toString();
		
	}
	public Map<String,Integer> getColIndex() {
		return colIndex;
	}

	public void setColIndex(Map<String,Integer> colIndex) {
		this.colIndex = colIndex;
	}

	public Map<String,Object> getExtra() {
		return extra;
	}

	public void setExtra(Map<String,Object> extra) {
		this.extra = extra;
	}

	public List<Map<String, Object>> getTargetRowData() {
		return targetRowData;
	}

	public void setTargetRowData(List<Map<String, Object>> targetRowData) {
		this.targetRowData = targetRowData;
	}
	
	
	

}
